/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.babystar.io
 *
 * 版权所有，侵权必究！
 */

package io.babystar.common.utils;

import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期处理
 *
 * @author Mark sunlightcs@gmail.com
 */
public class DateUtils {
	/** 时间格式(yyyy-MM-dd) */
	public final static String DATE_PATTERN = "yyyy-MM-dd";
	/** 时间格式(yyyy-MM-dd HH:mm:ss) */
	public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    // 创建“简体中文”的Locale
    static Locale localeCN = Locale.SIMPLIFIED_CHINESE;
    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd EEEE",localeCN);

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     * @param date  日期
     * @return  返回yyyy-MM-dd格式日期
     */
	public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     * @param date  日期
     * @param pattern  格式，如：DateUtils.DATE_TIME_PATTERN
     * @return  返回yyyy-MM-dd格式日期
     */
    public static String format(Date date, String pattern) {
        if(date != null){
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 字符串转换成日期
     * @param strDate 日期字符串
     * @param pattern 日期的格式，如：DateUtils.DATE_TIME_PATTERN
     */
    public static Date stringToDate(String strDate, String pattern) {
        if (StringUtils.isBlank(strDate)){
            return null;
        }

        DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);
        return fmt.parseLocalDateTime(strDate).toDate();
    }

    /**
     * 获取当天
     * @return
     */
    public static String getCurrentDay(){
        return format(new Date(), DATE_PATTERN);
    }

    /**
     * 根据周数，获取开始日期、结束日期
     * @param week  周期  0本周，-1上周，-2上上周，1下周，2下下周
     * @return  返回date[0]开始日期、date[1]结束日期
     */
    public static Date[] getWeekStartAndEnd(int week) {
        DateTime dateTime = new DateTime();
        LocalDate date = new LocalDate(dateTime.plusWeeks(week));

        date = date.dayOfWeek().withMinimumValue();
        Date beginDate = date.toDate();
        Date endDate = date.plusDays(6).toDate();
        return new Date[]{beginDate, endDate};
    }

    /**
     * 对日期的【秒】进行加/减
     *
     * @param date 日期
     * @param seconds 秒数，负数为减
     * @return 加/减几秒后的日期
     */
    public static Date addDateSeconds(Date date, int seconds) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusSeconds(seconds).toDate();
    }

    /**
     * 对日期的【分钟】进行加/减
     *
     * @param date 日期
     * @param minutes 分钟数，负数为减
     * @return 加/减几分钟后的日期
     */
    public static Date addDateMinutes(Date date, int minutes) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMinutes(minutes).toDate();
    }

    /**
     * 对日期的【小时】进行加/减
     *
     * @param date 日期
     * @param hours 小时数，负数为减
     * @return 加/减几小时后的日期
     */
    public static Date addDateHours(Date date, int hours) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusHours(hours).toDate();
    }

    /**
     * 对日期的【天】进行加/减
     *
     * @param date 日期
     * @param days 天数，负数为减
     * @return 加/减几天后的日期
     */
    public static Date addDateDays(Date date, int days) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusDays(days).toDate();
    }

    /**
     * 对日期的【周】进行加/减
     *
     * @param date 日期
     * @param weeks 周数，负数为减
     * @return 加/减几周后的日期
     */
    public static Date addDateWeeks(Date date, int weeks) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusWeeks(weeks).toDate();
    }

    /**
     * 对日期的【月】进行加/减
     *
     * @param date 日期
     * @param months 月数，负数为减
     * @return 加/减几月后的日期
     */
    public static Date addDateMonths(Date date, int months) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMonths(months).toDate();
    }

    /**
     * 对日期的【年】进行加/减
     *
     * @param date 日期
     * @param years 年数，负数为减
     * @return 加/减几年后的日期
     */
    public static Date addDateYears(Date date, int years) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusYears(years).toDate();
    }


    /**
     * 根据当前时间，添加或减去指定的时间量。例如，要从当前日历时间减去 5 天，可以通过调用以下方法做到这一点：
     * add(Calendar.DAY_OF_MONTH, -5)。
     * @param date 指定时间
     * @param num  为时间添加或减去的时间天数
     * @return
     */
    public static Date getBeforeOrAfterDate(Date date, int num) {
        //获取日历
        Calendar calendar = Calendar.getInstance();
        //当date的值是当前时间，则可以不用写这段代码。
        calendar.setTime(date);
        calendar.add(Calendar.DATE, num);
        //把日历转换为Date
        Date d = calendar.getTime();
        return d;
    }

    /**
     * 获取未来一周
     * @return
     */
    public static List<String> getFutureDate(){
        List<String> weekList = new ArrayList<>();
        for(int i=0;i<7;i++){
            Date nextDate = getBeforeOrAfterDate(new Date(),i);
            weekList.add(sdf.format(nextDate));
            System.out.println(sdf.format(nextDate));
        }
        return weekList;
    }

    /**
     * 取周一
     * @return
     */
    public static String getMonDay(String day){
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat(DATE_PATTERN);
        Calendar cld = Calendar.getInstance(Locale.CHINA);
        //以周一为首日
        cld.setFirstDayOfWeek(Calendar.MONDAY);
        try {
            //当前时间
            cld.setTimeInMillis(df.parse(day).getTime());
        }catch (ParseException e){
            e.printStackTrace();
        }
        //周一
        cld.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return df.format(cld.getTime());
    }

    /**
     * 取周日
     * @return
     */
    public static String getSunDay(String day){
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat(DATE_PATTERN);
        Calendar cld = Calendar.getInstance(Locale.CHINA);
        //以周一为首日
        cld.setFirstDayOfWeek(Calendar.MONDAY);
        try {
            //当前时间
            cld.setTimeInMillis(df.parse(day).getTime());
        }catch (ParseException e){
            e.printStackTrace();
        }
        //周一
        cld.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return df.format(cld.getTime());
    }

    /**
     * 根据日期获取 星期 （2019-05-06 ——> 星期一）
     * @param datetime
     * @return
     */
    public static String dateToWeek(String datetime) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        Date date;
        try {
            date = f.parse(datetime);
            cal.setTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //一周的第几天
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }

    public static  String weekToEn(String weekZh){
        Map<String,String> week = new HashMap<>();
        week.put("星期日", "Sun");
        week.put("星期一", "Mon");
        week.put("星期二", "Tue");
        week.put("星期三", "Wed");
        week.put("星期四", "Thu");
        week.put("星期五", "Fri");
        week.put("星期六", "Sat");
        return week.get(weekZh);
    }

    public static void main(String arg[]) throws Exception {
        List<String> list = DateUtils.getFutureDate();
        List<Map<String, String>> week = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, String> map = new HashMap<String, String>();
            String day = list.get(i);
            //2022-06-13 星期一
            map.put("dayStr", day);
            map.put("weekEn", DateUtils.weekToEn(day.substring(11,14)));
            //显示日
            map.put("day", day.substring(8, 10));
            //显示周
            if(i==0){
                map.put("week", "今天");
            }else if(i==1){
                map.put("week", "明天");
            } else{
                map.put("week", "周" + day.substring(13, 14));
            }
            week.add(map);
        }
        System.out.println(week);
    }

}
